import { useLocation } from 'umi';
import { Graph, Cell, Node, Color, Dom } from '@antv/x6';
import dagre from 'dagre';
import { useParams } from 'umi';
import { useEffect, useState } from 'react';
import { cxlq_c_zb } from '@/services';
import { Empty, message } from 'antd';

Graph.registerNode(
  'org-node',
  {
    width: 180,
    height: 80,
    markup: [
      {
        tagName: 'rect',
        attrs: {
          class: 'card',
        },
      },
      {
        tagName: 'text',
        attrs: {
          class: 'id',
        },
      },
      {
        tagName: 'text',
        attrs: {
          class: 'value',
        },
      },
      {
        tagName: 'text',
        attrs: {
          class: 'qs',
        },
      },
    ],
    attrs: {
      '.card': {
        // rx: 10,
        // ry: 10,
        refWidth: '100%',
        refHeight: '100%',
        fill: '#fff',
        stroke: '#999',
        strokeWidth: 1,
        pointerEvents: 'visiblePainted',
      },
      '.id': {
        refX: 0.1,
        refY: 0.3,
        fontSize: 20,
        textAnchor: 'left',
        textVerticalAnchor: 'middle',
      },
      '.value': {
        refX: 0.1,
        refY: 0.6,
        fontSize: 20,
        fontWeight: '600',
        textAnchor: 'left',
      },
      '.qs': {
        refX: 0.6,
        refY: 0.6,
        fontSize: 16,
        textAnchor: 'left',
      },
    },
  },
  true,
);

// 自定义边
Graph.registerEdge(
  'org-edge',
  {
    zIndex: -1,
    attrs: {
      line: {
        strokeWidth: 2,
        sourceMarker: null,
        targetMarker: null,
      },
    },
  },
  true,
);

export default () => {
  const { fl } = useParams<{ fl: string }>();
  const { state } = useLocation<{ gs: string; name: string }>();
  const [dataSource, setDataSource] = useState([]);
  useEffect(() => {
    cxlq_c_zb({
      time: fl,
      flid: '100',
    }).then((data) => {
      if (data.msg === '失败') {
        return message.error(data.content);
      }
      setDataSource(data.content);
    });
  }, []);

  // 自定义节点
  useEffect(() => {
    if (dataSource.length === 0) return;
    // 布局方向
    const dir: 'LR' | 'RL' | 'TB' | 'BT' = 'TB';

    // 创建画布
    const graph = new Graph({
      container: document.getElementById('container')!,
      scroller: false,
      interacting: false,
    });

    // 自动布局
    function layout() {
      const nodes = graph.getNodes();
      const edges = graph.getEdges();
      const g = new dagre.graphlib.Graph();
      g.setGraph({ rankdir: dir, nodesep: 16, ranksep: 16 });
      g.setDefaultEdgeLabel(() => ({}));

      const width = 200;
      const height = 90;
      nodes.forEach((node) => {
        g.setNode(node.id, { width, height });
      });

      edges.forEach((edge) => {
        const source = edge.getSource() as any;
        const target = edge.getTarget() as any;
        g.setEdge(source.cell, target.cell);
      });

      dagre.layout(g);

      graph.freeze();

      g.nodes().forEach((id) => {
        const node = graph.getCell(id) as Node;
        if (node) {
          const pos = g.node(id);
          node.position(pos.x, pos.y);
        }
      });

      edges.forEach((edge) => {
        const source = edge.getSourceNode()!;
        const target = edge.getTargetNode()!;
        const sourceBBox = source.getBBox();
        const targetBBox = target.getBBox();

        const gap =
          dir === 'TB'
            ? targetBBox.y - sourceBBox.y - sourceBBox.height
            : -sourceBBox.y + targetBBox.y + targetBBox.height;
        const fix = dir === 'TB' ? sourceBBox.height : 0;
        const y = sourceBBox.y + fix + gap / 2;
        edge.setVertices([
          { x: sourceBBox.center.x, y },
          { x: targetBBox.center.x, y },
        ]);
      });

      graph.unfreeze();
    }

    function createNode(id: string, value: string, qs: string) {
      return graph.createNode({
        shape: 'org-node',
        attrs: {
          '.id': {
            text: Dom.breakText(id, { width: 160, height: 60 }),
          },
          '.value': {
            text: Dom.breakText(value, { width: 160, height: 45 }),
          },
          '.qs': {
            text: Dom.breakText(qs, { width: 160, height: 45 }),
          },
        },
      });
    }

    function createEdge(source: Cell, target: Cell) {
      return graph.createEdge({
        shape: 'org-edge',
        source: { cell: source.id },
        target: { cell: target.id },
      });
    }

    const nodes = dataSource.map((item: any) => {
      return createNode(
        item.name,
        item.value,
        item.bj === '无变化' ? item.bj : `${item.bj}${item.shu}`,
      );
    });

    const edges = [
      createEdge(nodes[0], nodes[1]),
      createEdge(nodes[0], nodes[2]),
      createEdge(nodes[1], nodes[3]),
      createEdge(nodes[1], nodes[4]),
      createEdge(nodes[3], nodes[5]),
      createEdge(nodes[3], nodes[6]),
      createEdge(nodes[4], nodes[7]),
      createEdge(nodes[4], nodes[8]),
      createEdge(nodes[5], nodes[9]),
      createEdge(nodes[5], nodes[10]),
      createEdge(nodes[5], nodes[11]),
      createEdge(nodes[8], nodes[12]),
      createEdge(nodes[8], nodes[13]),
      createEdge(nodes[10], nodes[14]),
      createEdge(nodes[10], nodes[15]),
      createEdge(nodes[10], nodes[16]),
      createEdge(nodes[12], nodes[17]),
      createEdge(nodes[12], nodes[18]),
      createEdge(nodes[12], nodes[19]),
      createEdge(nodes[12], nodes[20]),
    ];

    graph.resetCells([...nodes, ...edges]);
    layout();
    graph.zoomTo(0.7);
    graph.centerContent();
  }, [dataSource]);

  return dataSource.length === 0 ? (
    <Empty style={{ marginTop: 60 }} />
  ) : (
    <div
      id="container"
      style={{
        width: '100%',
        height: '100%',
      }}
    />
  );
};
